/**
 * 主启动进程。
 *
 * @type {exports}
 */

var cluster = require("cluster");
var numCpus = require("os").cpus().length;
var logger = require("../utils/logger");

var toConnection = [];        //连接超时(从fork一个worker进程，到worker进程调用listen)
var toDisconnect = [];        //进程退出超时
var limitTime = 15000;

/**
 * 设置master时触发此事件
 */
cluster.on("setup", function () {
    logger.info("Setup master process!");
});

/**
 * 当一个新的worker进程被fork的时候，触发此事件
 */
cluster.on("fork", function (_worker) {
    logger.info("Fork a new worker with pid : ", _worker.process.pid);
    toConnection[_worker.id] = setTimeout(function () {
        logger.error("Something must be wrong with the process connection.");
    }, limitTime);
});

/**
 * 创建一个worker进程后，worker就会立刻回应一个online消息，触发cluster的online事件
 */
cluster.on("online", function (_worker) {
    logger.info("The worker responded after it was forked worker pid : %d", _worker.process.pid);
});

/**
 * 当worker调用listen时，master端触发此事件
 */
cluster.on("listening", function (_worker, _address) {
    logger.info("The worker is now connected to %s:%d.", _address.address, _address.port);
    clearTimeout(toConnection[_worker.id]);
});

/**
 * 当IPC通道被断开时，触发此事件
 */
cluster.on("disconnect", function (_worker) {
    logger.info("The Worker %d has disconnected. worker pid :%d", _worker.id, _worker.process.pid);
    toDisconnect[_worker.id] = setTimeout(function () {
        logger.error("Disconnect overtime!");
    }, limitTime);
});

/**
 * 当任何一个worker die时，触发此事件
 */
cluster.on("exit", function (worker, code, signal) {
    logger.info("Worker %d died (%s) , restarting....", worker.process.pid, signal || code);
    clearTimeout(toConnection[worker.id]);
    clearTimeout(toDisconnect[worker.id]);

    if (worker.suicide === true) {              //worker发送“自杀”信号时，自动创建新worker
        logger.info("worker进程自杀，不需要担心....");
    } else {
        createWorker();
    }
});

/**
 * 设置子进程的执行文件位置
 */
cluster.setupMaster({
    //exec: __dirname + "/workertmp.js"
    exec: __dirname + "/worker.js"
});

/**
 * 创建工作进程。
 */
var createWorker = function () {
    var worker = cluster.fork();

    worker.on("message", function (msg) {
        if (msg.type != 'publishreq')
            logger.info("Get a message form worker : ", msg);
    });
};

/**
 * 创建子进程。
 */
exports.run = function () {
    logger.info("主业务服务器应用角色启动.");
    for (var i = 0; i < numCpus; i++) {
        createWorker();
    }
};

/**
 * 主进程退出时杀掉所有的worker
 */
process.on("exit", function () {
    var workers = cluster.workers;
    for (var wid in workers) {
        if (workers[wid].hasOwnProperty("kill"))
            workers[wid].kill();
    }
});
